/*************************************************************************
 * @file: geomchecker.h
 * @date: 01/04/2012
 * TOPOL v1_0 - (c)copyright 2012 TEC/UFF
 *************************************************************************
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 ************************************************************************/

#ifndef _GEOMCHECKER
#define _GEOMCHECKER

// includes
//----------
#include "entity/ipoint.h"
#include <list>
using namespace std;

// forward declarations
//----------------------
class HEDModel;
class Edge;


/*!
 * CLASS
 * GeomChecker
 * 
 * This class is responsible to perform all necessary geometric tests, i.e.
 * it is part of decision making techniques, necessary to identify the
 * correct sequence of Euler Operators to call, as for example.
 * 
 * @author Andre Pereira (andremaues@id.uff.br)
 * @version 1.0.0
 * @see HEDModel
 */
class GeomChecker
{

public:

  ////////////////////////////////////////////////
  ///  Constructor and Destructor Declaration  ///
  ////////////////////////////////////////////////

  /**
   * @brief Constructs the object to perform geometric checks
   */
	GeomChecker();

  ////////////////////////////////////
  ///  PUBLIC Methods Declaration  ///
  ////////////////////////////////////

  /**
   * @brief Verifies if the model contains at least one vertex
   * @param _model is the model with all topological entities
   * @return bool is the results of the check
   */
  bool hasAnyVertex( HEDModel& _model );

  /**
   * @brief Verifies if the model contains a vertex with coordinates (x,y,z)
   * @param _model is the model with all topological entities
   * @param _id is the identity of the desired vertex if it was found
   * @param _x is the first coordinate of the point
   * @param _y is the second coordinate of the point
   * @param _z is the third coordinate of the point
   * @param _tol is the tolerance used in the attraction test
   * @return bool is the results of the check
   */
  bool hasVertexWithGivenCoords( HEDModel& _model, int& _id,
                                 double& _x, double& _y, double& _z, double _tol );

  /**
   * @brief Verifies if the model contains vertexes intersected by a curve segment
   * @param _model is the model with all topological entities
   * @param _curvePts is the given curve segment to look for the intersections
   * @param _n is the number of intersections found
   * @param _intersPts contains the coordinates of the intersection points 
   * @return bool is the results of the check
   */
  bool intersectsVertex( HEDModel& _model, double* _curvePts, int& _n, double* _intersPts );

  /**
   * @brief Verifies if the model contains edges intersected by a curve segment
   * @param _model is the model with all topological entities
   * @param _cp1 is the first point of the given curve segment to look for the intersections
   * @param _cp2 is the second point of the given curve segment to look for the intersections
   * @param _intersPts contains the coordinates of the intersection points 
   * @param _iEdges contains the edges intersected by the given segment
   * @return bool is the results of the check
   */
  bool intersectsCurves( HEDModel& _model, IPoint& _cp1, IPoint& _cp2,
                         list<IPoint>& _intersPts, list<Edge*>& _iEdges );

  /**
   * @brief Verifies if the point with coordinates (x,y,z) lies on an edge of the model
   * @param _model is the model with all topological entities
   * @param _id is the identity of the desired edge if it was found
   * @param _x is the first coordinate of the point
   * @param _y is the second coordinate of the point
   * @param _z is the third coordinate of the point
   * @param _tol is the tolerance used in the attraction test
   * @return bool is the results of the check
   */
  bool liesOnCurve( HEDModel& _model, int& _id, double& _x, double& _y, double& _z, double& _tol );


private:

  /////////////////////////////////////
  ///  PRIVATE Methods Declaration  ///
  /////////////////////////////////////

  // computes the intersection between two line segments
  int computeLineLineIntersection( double _x1, double _y1, double _x2, double _y2,
                                   double _x3, double _y3, double _x4, double _y4,
                                   double& _xi, double& _yi );

  // compares two numbers for a given tolerance
  int comp( double _a, double _b, double _tol );

  // compares two points for a given tolerance
  int contvv( double _x1, double _y1, double _x2, double _y2, double _tol );

};

#endif
